package com.jinzhi.common.filter;

import com.alibaba.fastjson.JSONObject;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayUtil;
import com.jinzhi.common.configconsts.wxconsts.LinkConfiggure;
import com.jinzhi.common.service.DictService;
import com.jinzhi.common.utils.*;
import com.jinzhi.common.vo.WxPayConfig;
import com.jinzhi.common.vo.WxPayVo;
import com.jinzhi.common.utils.wx.TemplateMessageEnum;
import com.jinzhi.oss.service.FileService;
import com.jinzhi.oss.service.OssService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.chain.Command;
import org.apache.commons.chain.Context;
import org.apache.commons.lang.StringUtils;
import org.apache.http.entity.ContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.swing.filechooser.FileSystemView;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;


/**
 * 微信链路之组上送微信支付（统一下单）
 */
@Slf4j
@Component
public class WxRequestFliter implements Command {
    @Autowired
    private WxPayConfig wxPayConfig;
    @Autowired
    private OssService ossService;
    @Autowired
    private FileService sysFileService;

    @Autowired
    private DictService dictService;

    private com.github.wxpay.sdk.WXPayConfig config;

    @Override
    public boolean execute(Context context) throws Exception {

        log.info("链路:微信支付执行到:上送微信支付");
        //获取返回对象
        ApiResult apiResult = (ApiResult) context.get(LinkConfiggure.API_RESULT);

        //获取支付对象
        WxPayVo wxPayVo = (WxPayVo) context.get(LinkConfiggure.WX_PAY_VO);

        //获取微信支付参数Map
        Map<String, String> requestMap = (Map<String, String>) context.get(LinkConfiggure.REQUEST_MAP);
        try {
            WXPay wxPay = new WXPay(config);

            //请求微信支付接口
            String result = wxPay.requestWithoutCert(wxPayConfig.getPayUrl(),
                    requestMap, wxPayConfig.getConnectTimeoutMs(),
                    wxPayConfig.getReadTimeoutMs());

            log.info("当前微信返回参数为:{}", result);

            if (StringUtils.isEmpty(result)) {
                apiResult.setCode(LinkConfiggure.WX_ERROR_CODE);
                apiResult.setMsg("微信返回参数为空");
                return true;
            }

            //将xml转成Json
            JSONObject mapToJSON = (JSONObject) JSONObject.toJSON(WXPayUtil.xmlToMap(
                    result));

            log.info("xml转Json:{}", mapToJSON);

            //此字段是通信标识，非交易标识，交易是否成功需要查看result_code来判断
            if (!LinkConfiggure.SUCCESS_CODE.equals(mapToJSON.getString(
                    "return_code"))) {
                apiResult.setCode(LinkConfiggure.WX_ERROR_CODE);
                apiResult.setMsg("通讯失败");
                return true;
            }

            if (!LinkConfiggure.SUCCESS_CODE.equals(mapToJSON.getString(
                    "result_code"))) {
                apiResult.setCode(LinkConfiggure.WX_ERROR_CODE);
                apiResult.setMsg("交易失败");
                return true;
            }

            //交易成功
            String prepay_id = mapToJSON.getString("prepay_id"); //预支付交易会话标识

            //保存prepay_id至缓存，为后面回调发送微信消息
            EhCacheUtil.put(wxPayVo.getOpenId() + ":prepay_id", prepay_id);

            //获取当前时间戳
            Long timeStamp = StringUtil.gettimeStamp();

            ////随机字符串
            String nonce_str = mapToJSON.getString("nonce_str");

            //定义加密Map
            Map<String, String> signMap = new HashMap<>();

            if (wxPayVo.getType() == 101) {
                signMap.put("appId", wxPayConfig.getAppId());
            } else {
                signMap.put("appId", wxPayConfig.getTraAppid());
            }
            signMap.put("nonceStr", nonce_str);
            signMap.put("package", StringUtil.getPrepay(prepay_id));
            signMap.put("signType", wxPayConfig.getSign_type());
            signMap.put("timeStamp", timeStamp.toString());

            //加密生成paySign
            String paySign = WXPayUtil.generateSignature(signMap,
                    wxPayConfig.getMerSecret());
            wxPayVo.setSign(paySign);
            wxPayVo.setNonce_str(nonce_str);
            wxPayVo.setPrepay_id(StringUtil.getPrepay(prepay_id));
            wxPayVo.setTimeStamp(timeStamp);

            if (LinkConfiggure.TRADE_TYPE_NATIVE.equals(wxPayVo.getTrade_type())) {
                //NATIVE -Native支付(扫码支付)
                String code_url = mapToJSON.getString("code_url"); //预支付交易会话标识
                String path = FileSystemView.getFileSystemView().getHomeDirectory() + File.separator + "testQrcode";
                String out_trade_no = wxPayVo.getOut_trade_no();
                String fileName;
                if(wxPayVo.getType()==101){
                    //根据考生报名id和随机生成的uuid加密命名二维码名称
                    Long stuSignUpId = Long.parseLong(EhCacheUtil.get(out_trade_no + ":stuSignUpId").toString());
                    fileName = PasswdUtils.get(String.valueOf(stuSignUpId), UUIDUtils.get());
                }else if(wxPayVo.getType()==102){
                    //根据课程订单id和随机生成的uuid加密命名二维码名称
                    Long courseOrderId = Long.parseLong(EhCacheUtil.get(out_trade_no + ":courseOrderId").toString());
                    fileName = PasswdUtils.get(String.valueOf(courseOrderId), UUIDUtils.get());
                }else{
                    //根据订单id和随机生成的uuid加密命名二维码名称
                    Long orderId = Long.parseLong(EhCacheUtil.get(out_trade_no + ":orderId").toString());
                    fileName = PasswdUtils.get(String.valueOf(orderId), UUIDUtils.get());
                }

                File file = QrCodeUtil.createQrCode(code_url, path, fileName + ".jpg");
                String url = this.url(file);
                wxPayVo.setCode_url(url);
            }

            apiResult.setCode(Integer.parseInt(TemplateMessageEnum.PUSH_SUCCESS.getKey()));
            apiResult.setMsg("微信支付返回成功");
            apiResult.setData(wxPayVo);
        } catch (Exception e) {
            log.error("上送微信支付异常", e.getMessage());
            apiResult.setCode(LinkConfiggure.WX_ERROR_CODE);
            apiResult.setMsg("上送微信支付异常");
            e.printStackTrace();
        }
        return false;
    }

    private String url(File file) {
        String url;
        Map<String,String> map = new HashMap<>();
        map.put("name","上传路径");
        map.put("type","file_position");
       // String file_position = dictService.selDicBy(map);//todo 这里需要在数据字典配置

        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            MultipartFile multipartFile = new MockMultipartFile(file.getName(), file.getName(),
                    ContentType.APPLICATION_OCTET_STREAM.toString(), fileInputStream);
//            //默认本地上传
//            if (null != file_position) {
//                url = sysFileService.upload(multipartFile.getBytes(), multipartFile.getOriginalFilename());
//            } else {
//                url = sysFileService.upload(multipartFile);
//            }
            url =  ossService.uploadFileOss(multipartFile);
            return url;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}